package com.th.apicenter.xinlang.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.th.apicenter.deduct.entity.ThDeduct;
import com.th.apicenter.kuaishou.service.KuaiShouService;
import com.th.apicenter.mapper.ThDeductMapper;
import com.th.apicenter.mapper.ThXlDataMapper;
import com.th.apicenter.tools.OkhttpClient;
import com.th.apicenter.xinlang.dto.ThXlNumDTO;
import com.th.apicenter.xinlang.entity.ThXlData;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Base64;
import java.util.Date;

@Service
@Slf4j
public class XinlangService {

    @Resource
    private ThXlDataMapper thXlDataMapper;

    @Autowired
    private KuaiShouService kuaiShouService;

    @Resource
    private ThDeductMapper thDeductMapper;

    //新浪回调地址
    private final static String xl_callback_url = "http://cnv.ad.sina.com.cn/track";

    //转化ID，可在新建转化时取到
//    private static String cnv_id = "n22576_1_122131";
//    private static String token = "3427c7f619e223175645a72edfef37f5";
//
//    private static String cnv_id_active = "n22576_1_122213";
//    private static String token_active = "e014796d863442e65fcd141f9430843f";

    /**
     * 20250428 新浪数据只做了真回传
     *
     * @param thXlData
     * @return
     */
    public String receive(ThXlData thXlData) {
        log.info("新浪检测接收到的数据：{}", thXlData);
        //判断是否回传
        thXlData.setCreateTime(new Date());
        thXlData.setUpdateTime(new Date());
        thXlDataMapper.insert(thXlData);
        kuaiShouService.clickXL(thXlData, "registry");
        return "数据已接收！";

    }


    /**
     * 20250428 新浪数据只做了真回传
     * 20250519 新浪考核改为激活
     *
     * @param thXlData
     * @return
     */
    public String active(ThXlData thXlData) {
        log.info("新浪检测接收到的数据：{}", thXlData);
        //判断是否回传
        thXlData.setCreateTime(new Date());
        thXlData.setUpdateTime(new Date());
        thXlDataMapper.insert(thXlData);
        kuaiShouService.clickXL(thXlData, "active");
        return "数据已接收！";

    }

    /**
     * 只有拉新
     *
     * @param clickId
     */
    public void callback(String clickId, String actionType) {
        Date currentTime = new Date();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        String date = formatter.format(currentTime);
        String startTime = date + " 00:00:00";
        String endTime = date + " 23:59:59";

        ThXlData thXlData = thXlDataMapper.selectById(clickId);

        String event_type = "";
        switch (actionType) {
            case "1":
                event_type = "registry";
                break;
        }

        if (null != thXlData) {
            thXlData.setIsKsCallback(1);
            if (null == thXlData.getKsActionType()) {
                thXlData.setKsActionType(actionType);
            } else if (null != thXlData.getKsActionType() && null == thXlData.getKsActionTypeO()) {
                thXlData.setKsActionTypeO(actionType);
            } else if (null != thXlData.getKsActionType() && null != thXlData.getKsActionTypeO() && null == thXlData.getKsActionTypeT()) {
                thXlData.setKsActionTypeT(actionType);
            }

            if ("1".equals(actionType)) {
                ThDeduct thDeduct = thDeductMapper.selectOne(new QueryWrapper<ThDeduct>()
                        .eq("type", "xl")
                        .eq("account_id", thXlData.getCnvId()));
                //判断是否扣量
                ThXlNumDTO thXlNumDTO = thXlDataMapper.queryNumByDate(thXlData.getCnvId(), startTime, endTime);
                if (thXlNumDTO.getPassbackNum() >= 4) {
                    BigDecimal x = new BigDecimal(thXlNumDTO.getPassbackNum()).divide(new BigDecimal(thXlNumDTO.getEffectiveNum()), 2, RoundingMode.CEILING);
                    BigDecimal percent = new BigDecimal(thDeduct.getPercent()).divide(new BigDecimal(100), 2, RoundingMode.CEILING);
                    if (percent.doubleValue() != 0 && new BigDecimal(1).subtract(x).compareTo(percent) < 0) {
                        log.info("需要扣量，不做操作!");
                        thXlData.setIsDeduct(1);
                    } else {
                        if (null != thXlData && !"".equals(event_type)) {
                            //拼接url
                            StringBuffer sb = new StringBuffer();
                            sb.append(xl_callback_url);
                            sb.append("?");
                            sb.append("cnv_id=" + thDeduct.getAccountId() + "&");
                            sb.append("click_id=" + thXlData.getClickId() + "&");
                            sb.append("bhv_time=" + System.currentTimeMillis());
                            String xlSign = createXLSign(thDeduct.getVivoToken(), sb.toString());
                            sb.append("&action=" + event_type + "&");
                            sb.append("sign=" + xlSign);
                            String callbackUrl = sb.toString();
                            log.info("新浪回传的url：{}", callbackUrl);
                            /**
                             * 新浪回传的接口返回：{"code":600100,"info":"转化成功归因"}
                             */
                            String xlResult = OkhttpClient.httpGet(callbackUrl);
                            log.info("新浪回传的接口返回：{}", xlResult);
                            thXlData.setIsXlPassback(1);
                        }
                    }
                } else {
                    if (null != thXlData && !"".equals(event_type)) {
                        //拼接url
                        StringBuffer sb = new StringBuffer();
                        sb.append(xl_callback_url);
                        sb.append("?");
                        sb.append("cnv_id=" + thDeduct.getAccountId() + "&");
                        sb.append("click_id=" + thXlData.getClickId() + "&");
                        sb.append("bhv_time=" + System.currentTimeMillis());
                        String xlSign = createXLSign(thDeduct.getVivoToken(), sb.toString());
                        sb.append("&action=" + event_type + "&");
                        sb.append("sign=" + xlSign);
                        String callbackUrl = sb.toString();
                        log.info("新浪回传的url：{}", callbackUrl);
                        /**
                         * 新浪回传的接口返回：{"code":600100,"info":"转化成功归因"}
                         */
                        String xlResult = OkhttpClient.httpGet(callbackUrl);
                        log.info("新浪回传的接口返回：{}", xlResult);
                        thXlData.setIsXlPassback(1);
                    }
                }
            }
            thXlData.setUpdateTime(new Date());
            thXlDataMapper.updateById(thXlData);
        }
    }

    /**
     * 只有拉新
     *
     * @param clickId
     */
    public void callback_active(String clickId, String actionType) {
        Date currentTime = new Date();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        String date = formatter.format(currentTime);
        String startTime = date + " 00:00:00";
        String endTime = date + " 23:59:59";

        ThXlData thXlData = thXlDataMapper.selectById(clickId);

        String event_type = "";
        switch (actionType) {
            case "1":
                event_type = "active";
                break;
        }

        if (null != thXlData) {
            thXlData.setIsKsCallback(1);
            if (null == thXlData.getKsActionType()) {
                thXlData.setKsActionType(actionType);
            } else if (null != thXlData.getKsActionType() && null == thXlData.getKsActionTypeO()) {
                thXlData.setKsActionTypeO(actionType);
            } else if (null != thXlData.getKsActionType() && null != thXlData.getKsActionTypeO() && null == thXlData.getKsActionTypeT()) {
                thXlData.setKsActionTypeT(actionType);
            }

            if ("1".equals(actionType)) {
                ThDeduct thDeduct = thDeductMapper.selectOne(new QueryWrapper<ThDeduct>()
                        .eq("type", "xl")
                        .eq("account_id", thXlData.getCnvId()));
                //判断是否扣量
                ThXlNumDTO thXlNumDTO = thXlDataMapper.queryNumByDate(thXlData.getCnvId(), startTime, endTime);
                if (thXlNumDTO.getPassbackNum() >= 4) {
                    BigDecimal x = new BigDecimal(thXlNumDTO.getPassbackNum()).divide(new BigDecimal(thXlNumDTO.getEffectiveNum()), 2, RoundingMode.CEILING);
                    BigDecimal percent = new BigDecimal(thDeduct.getPercent()).divide(new BigDecimal(100), 2, RoundingMode.CEILING);
                    if (percent.doubleValue() != 0 && new BigDecimal(1).subtract(x).compareTo(percent) < 0) {
                        log.info("需要扣量，不做操作!");
                        thXlData.setIsDeduct(1);
                    } else {
                        if (null != thXlData && !"".equals(event_type)) {
                            //拼接url
                            StringBuffer sb = new StringBuffer();
                            sb.append(xl_callback_url);
                            sb.append("?");
                            sb.append("cnv_id=" + thDeduct.getAccountId() + "&");
                            sb.append("click_id=" + thXlData.getClickId() + "&");
                            sb.append("bhv_time=" + System.currentTimeMillis());
                            String xlSign = createXLSign(thDeduct.getVivoToken(), sb.toString());
                            sb.append("&action=" + event_type + "&");
                            sb.append("sign=" + xlSign);
                            String callbackUrl = sb.toString();
                            log.info("新浪回传的url：{}", callbackUrl);
                            /**
                             * 新浪回传的接口返回：{"code":600100,"info":"转化成功归因"}
                             */
                            String xlResult = OkhttpClient.httpGet(callbackUrl);
                            log.info("新浪回传的接口返回：{}", xlResult);
                            thXlData.setIsXlPassback(1);
                        }
                    }
                } else {
                    if (null != thXlData && !"".equals(event_type)) {
                        //拼接url
                        StringBuffer sb = new StringBuffer();
                        sb.append(xl_callback_url);
                        sb.append("?");
                        sb.append("cnv_id=" + thDeduct.getAccountId() + "&");
                        sb.append("click_id=" + thXlData.getClickId() + "&");
                        sb.append("bhv_time=" + System.currentTimeMillis());
                        String xlSign = createXLSign(thDeduct.getVivoToken(), sb.toString());
                        sb.append("&action=" + event_type + "&");
                        sb.append("sign=" + xlSign);
                        String callbackUrl = sb.toString();
                        log.info("新浪回传的url：{}", callbackUrl);
                        /**
                         * 新浪回传的接口返回：{"code":600100,"info":"转化成功归因"}
                         */
                        String xlResult = OkhttpClient.httpGet(callbackUrl);
                        log.info("新浪回传的接口返回：{}", xlResult);
                        thXlData.setIsXlPassback(1);
                    }
                }
            }
            thXlData.setUpdateTime(new Date());
            thXlDataMapper.updateById(thXlData);
        }
    }


    /**
     * 生成新浪的签名编码（含填充符）
     *
     * @return
     */
    public String createXLSign(String token, String url) {
        byte[] keyBytes = token.getBytes(StandardCharsets.UTF_8);
        byte[] dataBytes = url.getBytes(StandardCharsets.UTF_8);

        // 2. 计算 HMAC-SHA1
        Mac mac = null;
        try {
            mac = Mac.getInstance("HmacSHA1");
            mac.init(new SecretKeySpec(keyBytes, "HmacSHA1"));
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        }
        byte[] hmacBytes = mac.doFinal(dataBytes);

        // 3. 进行 URL 安全的 Base64 编码（保留填充符）
        String sign = Base64.getUrlEncoder().encodeToString(hmacBytes);
        return sign;

    }

}
